/**
 * ESC 小票打印指令类
 */
/**
 * 
 * @param {int} w 
 */
function ESCCmds(w)
{
    var cmds = [], m = 0x00, cm = 0x00;
    var res = [];

    /**
     * 
     * @param {int} a  0 左对齐 1 居中 2 右对齐
     * @returns ESCCmds
     */
    this.align = (a)=>{
        cmds.push(0x1B, 0x61, [48,49,50][a]);
        return this;
    }

    /**
     * 初始化打印机, 清除缓冲区
     * @returns {ESCCmds}
     */
    this.start = ()=>{
        cmds.push(0x1B, 0x40); // ESC @
        return this;
    }

    /**
     * 设置, 取消加粗模式
     * @param {boolean} bold 
     * @returns {ESCCmds}
     */
    this.b = (bold)=>{
        m = (m & 0xF7) | (bold?0x08:0x00)
        return this;
    }

    /**
     * 设置字库
     * @param {int} font  0 12X24 1 9X17
     * @returns {ESCCmds}
     */
    this.font = (font)=>{
        m = (m & 0xFE) | (font==0? 0x00:0x01);
        return this;
    }

    /**
     * 设置, 取消下划线
     * @param {boolean} u true 下划线 false 取消下划线 
     * @returns {ESCCmds}
     */
    this.u = (u)=>{
        m = (m & 0x7F) | (u? 0x80:0x00); return this;
    }
    /**
     * 设置双倍高
     * @param {boolean} du  true 双倍高度, false 单倍高度
     * @returns {ESCCmds}
     */
    this.dh = (du)=>{
        m = (m & 0xEF) | (du?0x10:0x00); return this;
    }
    /**
     * 设置双倍宽
     * @param {boolean} du  true 双倍宽度, false 单倍宽度
     * @returns {ESCCmds}
     */
    this.dw = (du)=>{
        m = (m & 0xDF) | (du?0x20:0x00); return this;
    }

    /**
     * 设置双倍宽高
     * @param {boolean} du  true 双倍宽高, false 单倍宽高
     * @returns {ESCCmds}
     */
    this.dwh = (dwh)=>{
        m = (m & 0xCF) | (dwh?0x30:0x00);
        console.log('setdwh:', m)
        return this;
    }

    /**
     * 重置文字模式
     * @returns {ESCCmds}
     */
    this.reset = ()=>{
        m = 0x00;return this;
    }

    /**
     * 打印并走纸
     * @param {int} n 走纸 n 行
     * @returns {ESCCmds}
     */
    this.go = (n)=>{
        cmds.push(0x1B, 0x64, n); // ESC d n
        return this;
    }

    /**
     * 打印文本
     * @param {string} text 
     * @returns {ESCCmds}
     */
    this.txt = (text)=>{
        if(cm != m){
            cm = m; cmds.push(0x1B, 0x21, m);
        }
        if(cmds.length > 0){
            res.push(String.fromCharCode.apply(null, new Uint8Array(cmds))); cmds = [];
        }
        res.push(text);
        return this;
    }

    /**
     * 打印双列文本
     * @param {String} a 第一列内容
     * @param {String} b 第二列内容
     * @returns {ESCCmds}
     */
    this.twoc = (a, b)=>{
        let len = (a + b).replace(/[^\x00-\xff]/g, '**').length;
        const dw = (m != cm ? m : cm) & 0x20;
        console.log(m, cm, w, dw?2:1);
        return this.txt(a + ' '.repeat((w / (dw ? 2: 1))- len) + b)
    }
    /**
     * 打印一行点划线
     * @returns {ESCCmds}
     */
    this.dotl = ()=>{
        const dw = (m != cm ? m : cm) & 0x20;
        return this.txt('…'.repeat(w / (dw ? 4 : 2)))
    }

    /**
     * 生成缓冲区命令
     * @returns {ESCCmds}
     */
    this.cmds = ()=>{
        let r = res;
        res = [];
        if(cmds.length > 0){
            r.push(String.fromCharCode.apply(null, new Uint8Array(cmds)))
            cmds = [];
        }
        return r;
    }
}

/*
用法:
let cmds = new ESCCmds(32);
console.log('CMDS:', cmds.s().a(1).b(true).u(true).dw(true).dh(true).text('打印内容').cmd());

*/

export {
    ESCCmds
}